package com.suse.jd_system_server.filter;

import com.alibaba.fastjson.JSON;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.suse.jd_system_server.entity.User;
import com.suse.jd_system_server.utils.JwtUtils;
import com.suse.jd_system_server.utils.Result;
import com.suse.jd_system_server.utils.loginHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.servlet.HandlerExceptionResolver;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private JwtUtils jwtUtils;


    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    @Qualifier("handlerExceptionResolver")
    private HandlerExceptionResolver resolver;

    @Autowired
    private com.suse.jd_system_server.utils.loginHandler loginHandler;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String requestUrl = request.getRequestURI();
        //登录请求则放行
        if (requestUrl.contains("/login") || requestUrl.contains("/register") ||
                requestUrl.contains("/selectHotelList") || requestUrl.contains("/map")||
                requestUrl.contains("/selectProvince") || requestUrl.contains("/selectCity")
        ) {
            doFilter(request, response, filterChain);
            return;
        }
        //获取请求头信息
        String token = request.getHeader("token");

        if (StringUtils.isEmpty(token)) {
            //没有token
//           throw new RuntimeException("token错误");
//            resolver.resolveException(request, response, null,new RuntimeException("客户端信息非法！！！"));
//            request.setAttribute("errorMessage","该用户已被锁定!");
            MyException(response, "用户未登录");
        } else {
            //有则解析token,获取用户信息
            //解析token
//            Claim CluserId = jwtUtils.getUserFromToken(token).getClaim("userId");
            DecodedJWT CluserId = jwtUtils.getUserFromToken(token);
            if (CluserId == null) {
                MyException(response, "token错误");
                return;
            }
            Integer userId = CluserId.getClaim("userId").asInt();
            //从redis查看用户是否已经登录
            String struser = stringRedisTemplate.opsForValue().get("userid:" + userId);
            if (struser == null) {
                MyException(response, "用户未登录");
                return;
            }
            User user = new ObjectMapper().readValue(struser, User.class);
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user, null, null);
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            //放行
            doFilter(request, response, filterChain);
        }
    }

    private void MyException(HttpServletResponse response, String message) throws IOException {
        Result result = Result.buildFail(message);
        String json = JSON.toJSONString(result);
        response.setStatus(200);
        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");
        response.getWriter().print(json);
    }
}
